//-----------------------------------------------------------------------------
// Advanced Water - all about water render Pixel Shader
//-----------------------------------------------------------------------------

#include "AdvancedWaterCommon.hlsl"

#if ADVANCEDWATER_ID == ADVANCEDWATER_TYPE_SURFACERENDER

uniform sampler g_TextureBump		: register( s0 );		// Bumpmap tex (2D)
uniform sampler g_TextureRefraction : register( s1 );		// Refraction texture (2D)
uniform sampler g_TextureReflection : register( s2 );		// Reflection texture (2D)


#define DeepWaterColor		g_vConstantColor
#define WaterBumpFresnel	g_vWaterBumpFresnel
#define WaterDepthBlend		g_vWaterDepthBlend
//			g_DeepWaterColor : Deep water color
//			g_vWaterBumpFresnel.x : Refraction Bump scale
//			g_vWaterBumpFresnel.y : Reflection Bump scale
//			g_vWaterBumpFresnel.z : fresnelBias
//			g_vWaterBumpFresnel.w : fresnelPow
//			g_vWaterDepthBlend.x  :	MaxWaterDepthScale(0.5)
//			g_vWaterDepthBlend.y  : WaterBlendScale(0.02)


	half Fresnel(half NdotL, half fresnelBias, half fresnelPow)
	{
		half facing = 1.0f - NdotL;
		return max(fresnelBias + (1.0f-fresnelBias) * pow(facing, fresnelPow), 0.0f);
	}

    float4 ProcessPixel( VSOUT _input )
    {
		half3 vEye = _input.Eye;
		//half3 vLight = _input.Light;

		// Get bump layers
		half3 vBumpTexA = tex2D(g_TextureBump, _input.Wave0.xy).xyz;
		half3 vBumpTexB = tex2D(g_TextureBump, _input.Wave1.xy).xyz;
		half3 vBumpTexC = tex2D(g_TextureBump, _input.Wave2.xy).xyz;
		half3 vBumpTexD = tex2D(g_TextureBump, _input.Wave3.xy).xyz;
		
		// Average bump layers
		half3 vBumpTex = normalize(2.0f*(vBumpTexA + vBumpTexB + vBumpTexC + vBumpTexD) - 4.0f);

		// Apply individual bump scale for refraction and reflection
		half3 vRefrBump = vBumpTex.xyz * half3(WaterBumpFresnel.x, WaterBumpFresnel.x, 1);
		half3 vReflBump = vBumpTex.xyz * half3(WaterBumpFresnel.y, WaterBumpFresnel.y, 1);

		// Compute projected coordinates
		half2 vProj = (_input.ScreenPos.xy / _input.ScreenPos.w);
		half4 vReflection = tex2D(g_TextureReflection, vProj.xy + vReflBump.xy);
		half4 vRefrA = tex2D(g_TextureRefraction, vProj.xy + vRefrBump.xy);
		half4 vRefrB = tex2D(g_TextureRefraction, vProj.xy);

		//Mask occluders from refraction map
		half4 vRefraction = vRefrB * vRefrA.w + vRefrA * (1-vRefrA.w);
/*
		// Specular highlight
		half3 vReflectDir = normalize(reflect(-vLight, vReflBump));
		float stemp = max(0, dot(vEye, vReflectDir));
		stemp = pow(stemp, 64);
		float3 specular = float3(stemp, stemp, stemp);
*/
		// Compute Fresnel term
		half NdotL = max(dot(vEye, vReflBump), 0);
		half facing = 1 - NdotL;
		half fresnel = Fresnel(NdotL, WaterBumpFresnel.z, WaterBumpFresnel.w);

		half3 vConstWaterColor = half3(DeepWaterColor.r, DeepWaterColor.g, DeepWaterColor.b);
		// Use distance to lerp between refraction and deep water color

		half fDistScale = saturate(WaterDepthBlend.x*4 - _input.Wave0.z * WaterDepthBlend.y);
		half3 WaterDeepColor = vRefraction.xyz * fDistScale + vConstWaterColor * (1 - fDistScale);

		// Lerp between water color and deep water color
		half3 watercolor = vConstWaterColor * facing + WaterDeepColor * (1-facing);
		half3 cReflect = fresnel * vReflection;

		// Final color
        return float4( cReflect + watercolor, saturate(_input.Wave0.z * WaterDepthBlend.y) );  
   }

#else

// When ADVANCEDWATER_ID == ADVANCEDWATER_TYPE_REFRACTIONMASK, also use default shader
// ------------------------------------------------------------------------------------------------
// DEFAULT
// ------------------------------------------------------------------------------------------------
    float4 ProcessPixel( VSOUT _input )
    {
        return float4( 0.0f, 0.0f, 0.0f, 0.0f );
    }

#endif